/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#include "./vSetupConfig.h"
#include "../../Macros/vLogMacros.h"

namespace Vendetta {
	vSetupConfig::vSetupConfig(): vXmlInputStream(), vXmlOutputStream() {
		setBoolWriteType(vStringConverter::VBT_YESNO_C);
		vConfigOption opt;
		mpDeviceInfo = new vDeviceInfo;
		mpDeviceInfo->Init();

		opt.CurrentOption = "";
		mEntries<<vPair<vString, vConfigOption>("RenderSystem", opt);
		mEntries<<vPair<vString, vConfigOption>("VideoMode", opt);
		mEntries<<vPair<vString, vConfigOption>("Frequency", opt);
		mEntries<<vPair<vString, vConfigOption>("ColorDepth", opt);
		mEntries<<vPair<vString, vConfigOption>("FullScreen", opt);
		mEntries<<vPair<vString, vConfigOption>("VSync", opt);
		mEntries<<vPair<vString, vConfigOption>("GPUGeometry", opt);
		mEntries<<vPair<vString, vConfigOption>("SaveConfig", opt);
	}

	vSetupConfig::~vSetupConfig() {
		vDelete(mpDeviceInfo);
	}

	vBool vSetupConfig::SaveToFile(const vString& fileName) {
		if (mSaveConfig) {
			LOGS_INFO("Saving config file \"%s\".", fileName);
			return vXmlOutputStream::SaveToFile(fileName);
		}

		return false;	
	}

	vBool vSetupConfig::LoadFromFile(const vString& fileName) {
		return vXmlInputStream::LoadFromFile(fileName);
	}

	vDeviceInfo* vSetupConfig::DeviceInfoPtr() {
		return mpDeviceInfo;
	}

	vBool vSetupConfig::IsSetupValid() {
		return (mpDeviceInfo->IsValid() && mSaveConfig);
	}

	vVoid vSetupConfig::SetToSave(vBool bSave) {
		mSaveConfig = bSave;
	}

	vBool vSetupConfig::preSave() {
		for (vUInt uiIndex = 0; uiIndex < mEntries.Size(); uiIndex++) {
			vPair<vString, vConfigOption> elem = mEntries[uiIndex];
			if (mpDeviceInfo->mValidOptions.Contains(elem.First)) {
				mEntries[uiIndex].Second = mpDeviceInfo->mValidOptions[elem.First];
			}
			if (elem.First.IsEqual("SaveConfig")) {
				mEntries[uiIndex].Second.CurrentOption = vStringConverter::ToString(mSaveConfig, vStringConverter::VBT_YESNO_C);
			}
		}
		try {
			openTagForWrite("Config");
			for (vUInt uiIndex = 0; uiIndex < mEntries.Size(); uiIndex++) {
				vPair<vString, vConfigOption> elem = mEntries[uiIndex];
				openTagForWrite(elem.First);
				addText(elem.Second.CurrentOption);
				closeLastOpenedTagForWrite();
			}
			closeLastOpenedTagForWrite();
		} catch (vException& e) {
			throw vException("Can't save setup configuration to file. In vSetupConfig::prepareForSave because: %s", 
				e.ErrorMsg());
			return false;
		}

		return true;
	}

	vBool vSetupConfig::postLoad() {
		vBool bOK = false;

		try {
			openTagForRead("/Config");
			iterateChildTags();
			while (nextChildTag()) {
				if (mpDeviceInfo->mValidOptions.Contains(tagName())) {
					mpDeviceInfo->mValidOptions[tagName()].CurrentOption = textTag();
				}
				if (tagName().IsEqual("SaveConfig")) {
					for (vUInt uiIndex = 0; uiIndex < mEntries.Size(); uiIndex++) {
						vPair<vString, vConfigOption> elem = mEntries[uiIndex];
						if (tagName().IsEqual(elem.First)) {
							mEntries[uiIndex].Second.CurrentOption = textTag();
						}
					}
					mSaveConfig = vStringConverter::ToBool(textTag(), &bOK);
					if (!bOK) {
						mSaveConfig = false;
					}
				}
				std::cout<<tagName()<<": "<<textTag()<<std::endl;
			}

			closeAllOpenTagsForRead();
		} catch (vException&) {
			LOGS_ERROR("During vSetupConfig::postLoad.");
			return false;
		}
		return true;
	}
}